#ifndef MERA_H
#define MERA_H
#include "mera_global.h"
#include "decoding.h"
#include <QString>
#include <QFile>
#include <QSettings>
#include <QTextCodec>
#include <QPointF>
#include <QDebug>
#include <QColor>

class MERA;
class Parametr;

/// Структура атрибутов и данных параметра
typedef struct HeadeParametr {
    QString Name; ///< Имя параметра
    QString Char; ///< Имя характеристики
    QString XUnit; ///< Размерность по оси "X"
    QString YUnit; ///< Размерность по оси "Y"
    QString XFormat; ///< Формат данных по оси "X"
    QString YFormat; ///< Формат данных по оси "Y"
    double Start; ///< Время начальное (Начальное значение "X")
    double Step; ///< Дискретность
    double k1; ///< Коэффициент линейного преобразования
    double k0; ///< Коэффициент линейного преобразования
    double freq; ///< Частота
    quint8 fd;  ///< Флаг достоверности параметра
    inline bool operator>(const HeadeParametr &other){
        return Name>other.Name;
    }

    inline bool operator<(const HeadeParametr &other){
        return Name<other.Name;
    }

}HeadeParametr_t;

typedef struct TxData {
    Parametr *m_parent;
    Approx *tx;
    int column_size;
    double *column1;
    double *column2;

    void mnk();
    void lineal_pices();

    double* calc_poly();
    void calc_poly_part(vector<double> *output, int count);
    double* calc_lineal();
}TxData_t;

class MERASHARED_EXPORT Parametr :public  QIODevice
{
public:
    explicit Parametr(MERA *parent=nullptr);

    HeadeParametr_t header() const;

    QString name() const;

    void setName(const QString &name);

    QByteArray readSomeDat(qint64 size);

    QString path() const;

    QByteArray *yData() const;
    size_t unread_size();
    void setYData(QByteArray *newYData);
    void clearYData();

    QByteArray *xData() const;
    void setXData(QByteArray *newXData);


    //ParametrAppend.cpp
    quint64 append(float x, float y);
    quint64 append(double x, double y);
    quint64 append(double y);

    quint64 append(char x, char y);

    quint64 append(short x, short y);
    quint64 append(int x, int y);
    quint64 append(long  x, long  y);
    quint64 append(long long  x, long long  y);

    quint64 append(unsigned char x, unsigned char y);
    quint64 append(unsigned short x,unsigned short y);
    quint64 append(unsigned int x, unsigned  int y);
    quint64 append(unsigned long x, unsigned  long y);
    quint64 append(unsigned long long x, unsigned  long long y);

    Parametr &operator<<(const char &y);
    Parametr &operator<<(const float &y);
    Parametr &operator<<(const double &y);
    Parametr &operator<<(const short &y);
    Parametr &operator<<(const int &y);
    Parametr &operator<<(const long &y);
    Parametr &operator<<(const long long &y);
    Parametr &operator<<(const unsigned short &y);
    Parametr &operator<<(const unsigned int &y);
    Parametr &operator<<(const unsigned long &y);
    Parametr &operator<<(const unsigned long long &y);
    //========================


    inline bool operator>(const Parametr &other){
        return this->name()>other.name();
    }

    inline bool operator<(const Parametr &other){
        return this->name()<other.name();
    }

    Parametr &operator=(const QString &name);

    Parametr &operator<<(const QPointF &point);

    bool open(OpenMode mode);
    bool open_only(OpenMode mode);
    TxData_t *tx();

     MERA *mera();
private:
    HeadeParametr_t m_header;

    TxData_t m_tx;

    MERA *m_parent;

    // QIODevice interface
    QByteArray *m_yData, *m_xData;

    int m_unread_size;

    QFile *m_file;

    quint64 writeX();

    quint64 writeDat();

    quint64 readX();

    quint64 readDat();

    void openDat();

    quint64 readTx();

protected:
    qint64 readData(char *data, qint64 maxlen) override;
    qint64 writeData(const char *data, qint64 len) override;

};

class MERASHARED_EXPORT MERA : public QObject
{
public:
    MERA (QObject *parent=nullptr, QString file="");

    QSettings *meraHeader();


    void setCodec(QTextCodec *newCodec);

    void setCodecForWrite(QTextCodec *newCodecForWrite);

    void setCodecForRead(QTextCodec *newCodecForRead);

    bool load();

    QString path() const;

    const QList<Parametr *> &paramList() const;

signals:

protected:
    static bool readMera(QIODevice &device, QSettings::SettingsMap &map);
    static bool writeMera(QIODevice &device, const QSettings::SettingsMap &map);
private:
    QSettings m_meraHeader;
    QString m_path;
    QList<Parametr*> m_paramList;
};

#endif // MERA_H
